using System.Collections.Generic;
using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
using Verse.Noise;

namespace RI_Talisman
{
    public class CompImPowerFoundation : ThingComp
    {
        public List<ImFormationArea> formAreas = new List<ImFormationArea>();

        private Color fieldColor = Color.white;

        public CompProperties_ImPowerFoundation Props => (CompProperties_ImPowerFoundation)props;

        public List<ImFormationArea> FormAreas => formAreas;

        public bool Active => parent.GetComp<CompPowerTrader>()?.PowerOn ?? true;

        private bool CanLinkTo(CompImPowerFoundation other)
        {
            if (other == this)
            {
                return false;
            }
            return ImPowerFoundationUtility.CanLinkTo(parent.Position, other);
        }

        public void EstablishConnections()
        {
            if (!parent.Spawned)
            {
                return;
            }
            List<CompImPowerFoundation> list = new List<CompImPowerFoundation>();
            List<CompImPowerFoundation> list2 = new List<CompImPowerFoundation>();
            List<Thing> list3 = parent.Map.listerThings.ThingsOfDef(RI_T_DefOfs.ImPowerFoundation);
            foreach (Thing item in list3)
            {
                CompImPowerFoundation compImPowerFoundation = item.TryGetComp<CompImPowerFoundation>();
                if (compImPowerFoundation != null && CanLinkTo(compImPowerFoundation))
                {
                    if (parent.Position.x == compImPowerFoundation.parent.Position.x)
                    {
                        list2.Add(compImPowerFoundation);
                    }
                    else if (parent.Position.z == compImPowerFoundation.parent.Position.z)
                    {
                        list.Add(compImPowerFoundation);
                    }
                }
            }
            foreach (CompImPowerFoundation h in list)
            {
                foreach (CompImPowerFoundation v in list2)
                {
                    Thing thing = list3.FirstOrDefault((Thing x) => x.Position.x == h.parent.Position.x && x.Position.z == v.parent.Position.z);
                    if (thing != null)
                    {
                        ImFormationArea imFormationArea = new ImFormationArea(CellRect.FromLimits(thing.Position, parent.Position).ContractedBy(1), parent.Map);
                        imFormationArea.foundations = new List<CompImPowerFoundation>
                    {
                        this,
                        thing.TryGetComp<CompImPowerFoundation>(),
                        v,
                        h
                    };
                        TryAddArea(imFormationArea);
                    }
                }
            }
            for (int num = formAreas.Count - 1; num >= 0; num--)
            {
                foreach (CompImPowerFoundation foundation in formAreas[num].foundations)
                {
                    if (!foundation.TryAddArea(formAreas[num]))
                    {
                        RemoveArea(formAreas[num]);
                        break;
                    }
                }
            }
        }

        private void RemoveArea(ImFormationArea area)
        {
            foreach (CompImPowerFoundation foundation in area.foundations)
            {
                if (foundation.formAreas.Contains(area))
                {
                    foundation.formAreas.Remove(area);
                }
            }
            formAreas.Remove(area);
        }

        public bool TryAddArea(ImFormationArea newArea)
        {
            if (!formAreas.Contains(newArea))
            {
                for (int num = formAreas.Count - 1; num >= 0; num--)
                {
                    if (formAreas[num].MyRect.Overlaps(newArea.MyRect) && formAreas[num].MyRect != newArea.MyRect)
                    {
                        if (formAreas[num].MyRect.Area <= newArea.MyRect.Area)
                        {
                            return false;
                        }
                        RemoveArea(formAreas[num]);
                    }
                }
                formAreas.Add(newArea);
            }
            return true;
        }

        public override void PostSpawnSetup(bool respawningAfterLoad)
        {
            CompGlower compGlower = parent.TryGetComp<CompGlower>();
            if (compGlower != null)
            {
                fieldColor = compGlower.GlowColor.ToColor.ToOpaque();
            }
            EstablishConnections();
            foreach (ImFormationArea formArea in formAreas)
            {
                formArea.RecalculateBlockingThing();
            }
        }

        public override void PostDeSpawn(Map map)
        {
            for (int num = formAreas.Count - 1; num >= 0; num--)
            {
                RemoveArea(formAreas[num]);
            }
            foreach (Thing item in map.listerThings.ThingsOfDef(ThingDefOf.ShipLandingBeacon))
            {
                item.TryGetComp<CompImPowerFoundation>()?.EstablishConnections();
            }
        }

        public override void CompTickRare()
        {
            foreach (ImFormationArea formArea in formAreas)
            {
                formArea.RecalculateBlockingThing();
            }
        }

        public override void PostDrawExtraSelectionOverlays()
        {
            foreach (ImFormationArea formArea in formAreas)
            {
                if (formArea.Active)
                {
                    Color color = (formArea.Clear ? fieldColor : Color.red);
                    color.a = Pulser.PulseBrightness(1f, 0.6f);
                    GenDraw.DrawFieldEdges(formArea.MyRect.ToList(), color);
                }
                foreach (CompImPowerFoundation foundation in formArea.foundations)
                {
                    if (CanLinkTo(foundation))
                    {
                        GenDraw.DrawLineBetween(parent.TrueCenter(), foundation.parent.TrueCenter(), SimpleColor.White);
                    }
                }
            }
        }

        public override string CompInspectStringExtra()
        {
            if (!parent.Spawned)
            {
                return null;
            }
            string text = "";
            if (!Active)
            {
                text += "NotUsable".Translate() + ": " + "Unpowered".Translate().CapitalizeFirst();
            }
            for (int i = 0; i < formAreas.Count; i++)
            {
                if (!formAreas[i].Clear)
                {
                    if (!text.NullOrEmpty())
                    {
                        text += "\n";
                    }
                    text += "NotUsable".Translate() + ": ";
                    text = ((!formAreas[i].BlockedByRoof) ? ((string)(text + "BlockedBy".Translate(formAreas[i].FirstBlockingThing).CapitalizeFirst())) : ((string)(text + "BlockedByRoof".Translate().CapitalizeFirst())));
                    break;
                }
            }
            foreach (Thing item in parent.Map.listerThings.ThingsOfDef(ThingDefOf.ShipLandingBeacon))
            {
                if (item != parent && ImPowerFoundationUtility.AlignedDistanceTooShort(parent.Position, item.Position, Props.edgeLengthRange.min - 1f))
                {
                    if (!text.NullOrEmpty())
                    {
                        text += "\n";
                    }
                    text += "NotUsable".Translate() + ": " + "TooCloseToOtherBeacon".Translate().CapitalizeFirst();
                    break;
                }
            }
            return text;
        }
    }
}
